package com.zhongdaima.netty.analysis.part0.jdk.nio;

import java.io.IOException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

/**
 * 欢迎关注公众号“种代码“，获取博主微信深入交流
 * @author wangjianxin
 */
public class NioServerConnector {
    private final ServerSocketChannel serverSocketChannel;

    private final Selector selector;

    private final NioServerHandler nioServerHandler;

    public NioServerConnector(ServerSocketChannel serverSocketChannel) throws IOException {
        this.selector = Selector.open();
        this.serverSocketChannel = serverSocketChannel;
        //向selector注册Channel，感兴趣事件为OP_ACCEPT(即新连接接入)
        this.serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT, serverSocketChannel);
        this.nioServerHandler = new NioServerHandler();
        this.nioServerHandler.start();
    }

    public void start() {
        Thread serverConnector = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        if (NioServerConnector.this.selector.select() > 0) {
                            Set<SelectionKey> selectionKeys = NioServerConnector.this.selector.selectedKeys();
                            Iterator<SelectionKey> iterator = selectionKeys.iterator();
                            while (iterator.hasNext()) {
                                SelectionKey key = iterator.next();
                                try {
                                    if (key.isAcceptable()) {
                                        //新连接接入
                                        SocketChannel socketChannel = ((ServerSocketChannel) key.attachment()).accept();
                                        socketChannel.configureBlocking(false);
                                        //把新连接交给serverHandler
                                        NioServerConnector.this.nioServerHandler.register(socketChannel);
                                    }
                                } finally {
                                    iterator.remove();
                                }
                            }
                        }
                    } catch (IOException e) {

                    }
                }
            }
        });
        serverConnector.start();
    }
}
